/*
 *
 *  Copyright (C) 2010 Tal Eisenberg
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package tal.drivechain.module.properties;

import java.awt.Color;
import java.util.HashMap;
import java.util.StringTokenizer;
import org.w3c.dom.NodeList;
import tal.drivechain.chain.ChainNode;

/**
 *
 * @author Main
 */
public class ColorParser implements PropertyParser {

    public String getPropertyType() {
        return "Color";
    }

    public void setAttribures(HashMap<String, String> attributes, NodeList childeElements) throws IllegalArgumentException {
    }

    public Object parseProperty(String color) throws IllegalArgumentException {
        if (color.startsWith("dark.")) {
            return darker((Color)parseProperty(color.substring(5)));
        } else if (color.startsWith("light.")) {
            return lighter((Color)parseProperty(color.substring(6)));
        } else if (color.startsWith("hue+.")) {
            return hueplus((Color)parseProperty(color.substring(5)));
        } else if (color.startsWith("hue-.")) {
            return hueminus((Color)parseProperty(color.substring(5)));
        } else if (color.startsWith("sat+.")) {
            return satplus((Color)parseProperty(color.substring(5)));
        } else if (color.startsWith("sat-.")) {
            return satminus((Color)parseProperty(color.substring(5)));
        } else if (color.startsWith("xor.")) {
            return xor((Color)parseProperty(color.substring(4)));
        } else if (color.startsWith("red+.")) {
            Color c = (Color)parseProperty(color.substring(5));
            return new Color(c.getRed() + 77, c.getGreen(), c.getBlue());
        } else if (color.startsWith("green+.")) {
            Color c = (Color)parseProperty(color.substring(7));
            return new Color(c.getRed(), c.getGreen() + 77, c.getBlue());
        } else if (color.startsWith("blue+.")) {
            Color c = (Color)parseProperty(color.substring(6));
            return new Color(c.getRed(), c.getGreen(), c.getBlue() + 77);
        } else if (color.startsWith("red-.")) {
            Color c = (Color)parseProperty(color.substring(5));
            return new Color(c.getRed() - 77, c.getGreen(), c.getBlue());
        } else if (color.startsWith("green-.")) {
            Color c = (Color)parseProperty(color.substring(7));
            return new Color(c.getRed(), c.getGreen() - 77, c.getBlue());
        } else if (color.startsWith("blue-.")) {
            Color c = (Color)parseProperty(color.substring(6));
            return new Color(c.getRed(), c.getGreen(), c.getBlue() - 77);
        }


        color.trim().toLowerCase();
        Color c;
        if (color.equals("black")) c =  Color.BLACK;
        else if (color.equals("blue")) c =  Color.BLUE;
        else if (color.equals("cyan")) c = Color.CYAN;
        else if (color.equals("darkgray")) c = Color.DARK_GRAY;
        else if (color.equals("gray") || color.equals("grey")) c = Color.GRAY;
        else if (color.equals("green")) c = Color.GREEN;
        else if (color.equals("lightgray")) c = Color.LIGHT_GRAY;
        else if (color.equals("magenta")) c = Color.MAGENTA;
        else if (color.equals("orange")) c = Color.ORANGE;
        else if (color.equals("pink")) c = Color.PINK;
        else if (color.equals("red")) c = Color.RED;
        else if (color.equals("white")) c = Color.WHITE;
        else if (color.equals("yellow")) c = Color.YELLOW;
        else {
            StringTokenizer tokenizer = new StringTokenizer(color, ",");
            if (tokenizer.countTokens()!=3)
                throw new IllegalArgumentException("Invalid color definition (3 numbers are required): " + color);
            else {
                try {
                    int red = Integer.parseInt(tokenizer.nextToken().trim());
                    int green = Integer.parseInt(tokenizer.nextToken().trim());
                    int blue = Integer.parseInt(tokenizer.nextToken().trim());
                    c = new Color(red, green, blue);
                } catch (NumberFormatException n) {
                    throw new IllegalArgumentException("Invalid color definition: " + color);
                }
            }
        }
        return c;
    }

    public String propToString(Object property, ChainNode context) {
        Color color = (Color)property;
        return color.getRed() + ", " + color.getGreen() + ", " + color.getBlue();
    }

    public static Color lighter(Color color) {
        float[] hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null);
        float b = hsb[2] + (float)0.1;
        if (b>1) b=1f;
        return Color.getHSBColor(hsb[0], hsb[1], b);
    }

    public static Color lighterBy(Color color, float d) {
        float[] hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null);
        float b = hsb[2] * d;
        if (b<0) b=0f;
        return Color.getHSBColor(hsb[0], hsb[1], b);
    }

    public static Color darker(Color color) {
        float[] hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null);
        float b = hsb[2] - 0.1f;
        if (b<0) b=0f;
        return Color.getHSBColor(hsb[0], hsb[1], b);
    }

    public static Color hueplus(Color color) {
        float[] hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null);
        float h = hsb[0] + 0.1f;
        if (h>1) h=1f;
        return Color.getHSBColor(h, hsb[1], hsb[0]);
    }

    public static Color hueminus(Color color) {
        float[] hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null);
        float h = hsb[0] - 0.1f;
        if (h<0) h=0f;
        return Color.getHSBColor(h, hsb[1], hsb[0]);
    }

    public static Color satplus(Color color) {
        float[] hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null);
        float s = hsb[1] + 0.1f;
        if (s>1) s=1f;
        return Color.getHSBColor(hsb[0], s, hsb[2]);
    }

    public static Color satminus(Color color) {
        float[] hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null);
        float s = hsb[1] - 0.1f;
        if (s<0) s=0f;
        return Color.getHSBColor(hsb[0], s, hsb[2]);
    }

    public static Color xor(Color color) {
        return new Color(color.getRed()^255, color.getGreen()^255, color.getBlue()^255);
    }


}
